﻿using System;
using System.Xml.Serialization;
using EPiServer.Core;
using EPiServer.SpecializedProperties;
using TemplateFoundation.Core;
using TemplateFoundation.CustomProperties;
using TemplateFoundation.UserControls;

namespace TemplateFoundation.WebControls.PropertyControls
{
    /// <summary>
    /// Base class for user controls used to render a user control property
    /// </summary>
    /// <typeparam name="T">The data type for the property, should match the data type of the associated UserControlProperty</typeparam>
    /// <seealso cref="UserControlPropertyBase"/>
    [Serializable]
    public abstract class PropertyUserControlBase<T> : UserControlBase where T : class
    {
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (IsPostBack)
            {
                // We need to set the value again to ensure ViewState is up to date (for example if the value type is a collection which has been modified)
                Value = Value;
            }
        }

        /// <summary>
        /// Gets or sets the property value
        /// </summary>
        [XmlIgnore]
        public virtual T Value
        {
            get
            {
                return ViewState["Value"] as T;
            }
            set
            {
                ViewState["Value"] = value;
            }
        }

        /// <summary>
        /// Occurs when a postback is triggered by the "Save", "Save and view", or "Save and publish" button
        /// </summary>
        public event EventHandler<EditPageEventArgs> PropertySave;

        /// <summary>
        /// Used to set the Value property
        /// </summary>
        /// <param name="e"></param>
        public virtual void OnPropertySave(EditPageEventArgs e)
        {
            EventHandler<EditPageEventArgs> handler = PropertySave;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        /// <summary>
        /// Occurs when the user control should be set up based on the Value
        /// </summary>
        /// <remarks>This happens when the user control is loaded without postback, or when a postback occurs because of a tab switch</remarks>
        public event EventHandler<EditPageEventArgs> PropertyLoad;

        /// <summary>
        /// Used to get the Value property and set up the property control
        /// </summary>
        /// <param name="e"></param>
        public virtual void OnPropertyLoad(EditPageEventArgs e)
        {
            EventHandler<EditPageEventArgs> handler = PropertyLoad;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        /// <summary>
        /// Gets or sets the associated PropertyData object
        /// </summary>
        public PropertyData PropertyData { get; set; }
    }

    /// <summary>
    /// Base class for user controls used to render a user control property with a string Value type
    /// </summary>
    /// <seealso cref="UserControlPropertyBase"/>
    [Serializable]
    public abstract class PropertyUserControlBase : PropertyUserControlBase<string>
    {

    }
}
